Skip to content

feat(dynacell): Spotlight v2 arm leaves, controls and eval waves - #507

Merged
alxndrkalinin merged 36 commits into
dynacell-modelsfrom
dynacell-spotlight-v2-evals
Sep 30, 2026
Merged

alxndrkalinin merged 36 commits into
dynacell-modelsfrom
dynacell-spotlight-v2-evals

Conversation

@alxndrkalinin

@alxndrkalinin alxndrkalinin commented Sep 29, 2026 •

Copy link
Copy Markdown
Collaborator

Follow-up to #498 (the SegAuxDice loss and its engine hooks). This branch holds the Spotlight v2 experiment configs: which arms get trained, how they are predicted, and how their predictions are scored against each family's own baseline. The question it answers is whether adding a segmentation-aware auxiliary loss improves a family over the same model trained without it. It covers FNet, UNeXt2 (from scratch), pix2pix and CELL-Diff, in 2D and 3D.

What's in it

Code (10 non-config files, +455/-45)

  • mask_conditioning.CondMaskSource gains threshold="otsu". It thresholds each predict window at the Otsu value of its own voxels, so a C-cond mask survives an intensity-scale shift between iPSC and A549. The fixed float threshold tuned on iPSC marked 96-97% of A549 voxels as foreground. A constant window gives an all-background mask. Three tests in test_training_integration.py cover this, including an affinely rescaled store where the float threshold fails and Otsu does not.

  • tools/generate_spotlight_v2_leaves.py generates every arm's fit and predict leaves from its baseline leaf in one pass, so an arm and its control share one recipe by construction. The arms are:

    • segaux, segauxself, cjoint/ccond, the UNeXt2-2D l1* rebuild, and last (predict-only) arms
    • seed1, segaux_seed1 and v2_seed1 second draws
    • an FNet-3D nucleus loss-weight sweep (segaux_halfw x0.5, segaux_doublew x2)

    Its test pins the leaf counts (56 fits / 226 predicts). It also pins that each derived arm differs from its source only by the intended keys: seed, weight scale or renames.

  • tools/spotlight_v2_eval_roster.yaml and generate_spotlight_v2_eval_configs.py hold the eval waves (wave1*, wave2a-wave2f) and ctrl1. ctrl1 is a cosmetic-vs-structural control: each 3D nucleus baseline's A549 prediction histogram-matched per volume to its segaux arm's. Each (organelle, model, leg) appears in exactly one wave. A store gate refuses absent or partial prediction stores.

  • evaluation/paths.py and tools/generate_grouped_eval_configs.py register the new model tokens.

  • test_only_measured_slow_fits_get_the_long_wall allows the 7-day wall for the UNeXt2-3D v2_seed1/segaux_seed1 draws. They are the same recipe as the measured v2/segaux fits (~2.0 ep/h, ~100 h for 200 epochs).

Configs (149 files): generated fit/predict leaves under configs/benchmarks/virtual_staining/{nucleus,membrane}/ and grouped eval buckets under _internal/leaf/grouped/spotlight_v2_*. Every one is regenerable from the two generators above. Eval outputs go to a separate root (.../_spotlight_v2), never the canonical dirs the paper tables read.

Merge: dynacell-models @ c39d59f merged in (f1a0245, no conflicts). It brings #499-#504 and #506, so evals launched from this branch now need the cpdino-eval-cubic090a2 venv (the run_eval_direct.slurm default).

Testing

On 03249b6 (tools/paths/config suites were last run on 9cad49e; 03249b6 only touches mask_conditioning.py and its test), against the workspace .venv with the worktree's src dirs on PYTHONPATH:

  • applications/dynacell/tools/ + tests/test_paths.py + tests/test_benchmark_config_composition.py: 2676 passed, 0 failed
  • tests/test_training_integration.py -k "cond or mask or seg_aux or segaux": 32 passed, 0 failed
  • generate_spotlight_v2_leaves.py: 282 leaves, 0 written. The simplify and review commits leave every generated leaf byte-identical.

Review follow-ups

  • /simplify:
    • The leaf generator now composes recipes instead of copying them: l1segaux/l1seed1 compose l1, second draws come from a SEED_SOURCES map, and their long wall is derived.
    • The dead C-cond placeholder is gone.
    • The generator tests share one leaf generation (150 s -> 121 s).
    • _SPOTLIGHT_ARM_MODELS is derived from ARMS.
    • The roster comments are back on their waves.
  • Internal review:
    • CondMaskSource refuses to read unwritten mask windows. The writer zero-fills, so such a window read back as 0.0 and C-cond conditioned silently on an empty mask.
    • The long-wall allow-list no longer names a nucleus segaux_seed1 leaf that does not exist.
    • A stale docstring is fixed.
  • Copilot: the first two reviews had 0 findings. The third flagged that a partly written mask window, zeros mixed with predictions, passes a constant-value check. CondMaskSource now requires the writer's per-channel completion marker instead (03249b6). All 272 positions of the 8 live C-cond mask sources carry that marker.

Notes for review

  • The analysis scripts and readouts live in the gitignored applications/dynacell/experiments/2026-09-24_spotlight-v2/ and are not part of this PR.
  • The _seed1 and sweep leaves exist because of a measured noise floor. On A549 the two FNet baseline draws differ by up to 0.39 Dice, so an arm effect only counts when it has the same sign against both baseline draws.
  • Several fits and predicts are still running from these leaves. Changing a leaf's recipe here would desynchronize it from checkpoints already on disk.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J

alxndrkalinin and others added 27 commits September 26, 2026 02:24
…2 wave1c

8 buckets for the predict-only pix2pix2d_unetvit_last stores (nucleus
and membrane, iPSC plus 3 A549 legs), so that GAN arm-vs-baseline
compares final checkpoints on both sides.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
…n L1

The MixedLoss UNeXt2-2D membrane baseline is a failed fit (Dice 0.380),
and the L1-only probe trains (0.889), matching segaux (0.874). So the
segaux arm only showed that a seg term rescues a broken recipe as well
as fixing the loss does. This adds the comparison on the recipe that
trains:

- l1segaux: L1 + SegAuxDice at w=0.18, calibrated on the l1 probe's
  best checkpoint (median ||grad base||/||grad dice|| over 20 batches,
  IQR 0.15-0.27; the replay matches the recorded val loss to 1.0%).
- l1seed1: L1 at seed 1, as the noise floor.
- The l1 probe also predicts the 3 A549 legs, as their baseline.

A test pins each new arm to the l1 probe plus its own keys.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
t = 0.30 in the FNet-2D segaux prediction's units (a z-score of the
training target): the mean-Dice optimum of (pred >= t) vs fg_mask over
20 training-store val FOVs (0.774, with 0.25-0.40 within 0.0021). No
test FOV informed it. The 3D C-cond arm keeps the unparseable
placeholder until its FNet-3D segaux store exists and is tuned.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
31 conditions in 8 buckets:
- CELL-Diff-2D segaux, seed1 and cjoint.
- UNeXt2-2D nucleus segaux and seed1.
- The first segauxself arms (FNet-2D and CELL-Diff-2D, nucleus).
- The jointsteps probe.
- The l1 probe's A549 legs, whose iPSC leg is in wave1b.
All stores pass the completeness gate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
55 conditions in 8 buckets:
- The 2D segauxself arms and the L1-recipe UNeXt2-2D membrane arms.
- FNet-3D segaux and seed1.
- The finished pix2pix3d and CELL-Diff-3D test legs.
- The CELL-Diff-2D C-cond arm.
wave1 keeps only the legs still predicting, plus the not-yet-predicted
UNeXt2-3D and 3D C-cond arms, narrowed per leg so that no condition
sits in two waves.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
t = 0.40, in the FNet-3D segaux prediction's units (a z-score of the
training target). It is the mean-Dice optimum of (GT target >= t) vs
fg_mask over 20 training-store val FOVs x 44 planes: 0.699, with
0.30-0.50 within 0.004. A CPU forward of FNet-3D over val FOVs takes
about 57 min per FOV, so the prediction-based optimum (0.10 above the
GT one in 2D) is unmeasured for 3D. No test FOV informed the choice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
3 conditions (segaux zikv; v2 mock and denv) that finished after wave2a;
removed from wave1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
Most arm effects in the v2 readouts are A549-transfer effects, e.g.
FNet-3D nucleus segaux Dice +0.40 and membrane -0.38. The seed
replicates were iPSC-only, so those effects had no noise floor. The
FNet-3D baseline store also predates this pipeline (April, provenance
unknown), and its seed replicate checks it on A549. This adds 30
predict leaves: seed1 x {fnet2d, UNeXt2-2D, pix2pix2d, CELL-Diff-2D} x 2
organelles, FNet-3D nucleus seed1 and UNeXt2-2D l1seed1, each x 3 A549
legs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
A fixed threshold tuned on iPSC does not transfer. FNet's A549
predictions sit on a different intensity scale: FNet-2D segaux has a
median of about +1.2 and p99 of about +18, against +0.04 / +2.1 on
iPSC. t = 0.30 therefore marked 96-97% of A549 pixels foreground, and
C-cond A549 Dice fell by 0.30. threshold="otsu" thresholds each window
at its own Otsu level; a constant window gives an all-background mask.
On the 20 iPSC val FOVs its Dice vs fg_mask is 0.769, against 0.774 for
the tuned t=0.30. The float path is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
The fixed thresholds (2D 0.30, 3D 0.40) were tuned on iPSC and
conditioned CELL-Diff on near-all-foreground masks on A549. All 8
C-cond predict leaves now use threshold="otsu", so the arm has one
label-free definition on every test leg.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
…re-predict

Its wave2a scores used the fixed t=0.30 mask. They are kept aside as
<leg>.fixed_t030 in the v2 root, and the arm returns to wave1 until the
Otsu predicts finish.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
… v2 as wave2c

The seed1 A549 predicts give the A549 run-to-run noise floor that the
arm-vs-baseline deltas are judged against; fnet3d_paper_seed1 also checks
whether the April FNet-3D baseline store is representative. The fresh
UNeXt2-3D membrane baseline moves out of the still-pending wave1.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
…ix2pix3d v2

On A549 the two FNet baseline draws differ by up to 0.39 Dice, so an arm
effect only counts when it holds against both baseline draws, and every arm
and the pix2pix3d v2 baseline so far rest on one run. A `<suffix>_seed1`
arm re-draws its source arm with seed_everything: 1 and nothing else:
fnet2d_segaux_seed1 (nucleus+membrane), fnet3d_paper_segaux_seed1 (nucleus)
and pix2pix3d_unetvit_v2_seed1 (nucleus+membrane), each with its 4 predicts.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
PAPER_KEY, the grouped generator's token map, _DETERMINISTIC_MODELS and the
Spotlight arm skip set gain fnet2d_segaux_seed1, fnet3d_paper_segaux_seed1
and pix2pix3d_unetvit_v2_seed1, so their stores score under their own keys
and stay out of the canonical buckets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
… wave2d

Both fits finished at ep199/200; predicts are from --ckpt best (segaux
ep95, v2 ep81, read from each last.ckpt's best_k_models). They move out of
the still-pending wave1 so they do not wait on the CELL-Diff-3D legs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
…rane segauxself ZIKV as wave2e

The CELL-Diff-2D and -3D C-cond iPSC predicts and the CELL-Diff-2D
membrane segauxself ZIKV predict finished; score them now instead of
waiting on the rest of wave1. wave1 keeps only the C-cond A549 legs,
so no condition is scored in two waves.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
…aseline

wave2d scored the UNeXt2-3D nucleus segaux arm against its v2 baseline:
on the three A549 legs instance Dice +0.029..+0.047 and PCC
-0.020..-0.025, bootstrap CIs excluding 0. The plan drew this baseline a
second time only if that verdict came back non-null, because on A549 a
single draw has proved unreliable (the FNet baseline draws differ by up
to 0.39 Dice). The replicate differs from the v2 leaf only in names and
seed_everything: 1, and keeps the 7-day 4-GPU wall.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
…l token

PAPER_KEY, the grouped generator's token map, _DETERMINISTIC_MODELS and
the Spotlight arm skip set gain fcmae_vscyto3d_scratch_v2_seed1
(unext2_v2_seed1), so its stores score under their own key and stay out
of the canonical buckets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
FNet-3D nucleus is the one Spotlight v2 cell whose A549 effect held
against both baseline draws (Dice +0.21..+0.44, mAP +0.15..+0.22 at the
calibrated w=1.9), so it is the first Stage 2 ablation: the segaux arm
at 0.5x and 2x seg_aux_weight (0.95, 3.8), nothing else changed. The
test pins that each sweep leaf equals the segaux arm's up to names and
the scaled weight.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
…tokens

PAPER_KEY, the grouped generator's token map, _DETERMINISTIC_MODELS and
the Spotlight arm skip set gain fnet3d_paper_segaux_halfw and
fnet3d_paper_segaux_doublew, so their stores score under their own keys
and stay out of the canonical buckets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
…s eval model tokens

PAPER_KEY, the grouped generator's token map, _DETERMINISTIC_MODELS and the
Spotlight arm skip set gain fnet3d_paper_histmatch,
pix2pix3d_unetvit_v2_histmatch and fcmae_vscyto3d_scratch_v2_histmatch: each
3D nucleus v2 baseline's A549 prediction histogram-matched per volume to its
segaux arm, the control that tells a cosmetic intensity effect on the
segmenter from a structural one. Without the keys the stores would collapse
onto their baselines by longest prefix. They have no training leaf, so the
tests pin them as a separate controls set next to the leaf generator's arms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
Scores the FNet-2D segaux second draw (nucleus and membrane, all four
legs) and the UNeXt2-3D membrane segaux arm (fit ep199/200, predicted
from --ckpt best ep125). The membrane segaux arm moves out of wave1 so
each (organelle, model, leg) stays in exactly one wave. 12 conditions,
8 buckets; the store gate passed on all 12.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
…oster wave ctrl1

On A549 the 3D nucleus segaux arms beat their baselines on instance Dice and
mAP while PCC drops and semantic Dice barely moves, which an intensity-only
change the segmenter prefers could also produce. ctrl1 scores each v2
baseline (FNet-3D, pix2pix3d, UNeXt2-3D) with its segaux arm's per-volume
intensity histogram imposed and its spatial structure kept, on the three
A549 legs. If the matched baselines recover most of the gain, the effect is
cosmetic. The stores sit outside the canonical grammar, so the entries give
pred_paths; the three generated buckets hold three conditions each.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
…baseline

The UNeXt2-3D membrane segaux arm came back non-null in wave2f and, unlike
every other family, improves in-domain on every metric: iPSC mAP +0.128,
instance Dice +0.099, PCC +0.027, SI_SSIM +0.034, CellDINO KID -3.2
(bootstrap CIs exclude 0). That is a single baseline draw, and on A549
the FNet baselines' two draws differ by up to 0.39 Dice, so the membrane
v2 baseline gets its seed_everything: 1 replicate, as nucleus already has.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
The v2_seed1 fit leaves (nucleus and membrane) take the long 4-GPU wall
from generate_spotlight_v2_leaves.LONG_WALL_MODELS, but the allow-list
in test_only_measured_slow_fits_get_the_long_wall only named the v2 and
segaux leaves, so both failed. A second draw is the same recipe with
seed_everything: 1, so the measured ~2.0 ep/h (~100 h for 200 epochs)
applies unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
The UNeXt2-3D membrane segaux arm is the only one that improves every
in-domain metric (wave2f: iPSC mAP +0.128, instance Dice +0.099, PCC
+0.027, SI_SSIM +0.034, KID -3.2; A549 Dice +0.12..+0.18). With the
v2_seed1 baseline draw already queued, a seed_everything: 1 draw of
the arm completes the 2x2 (arm draw x baseline draw) that the A549
verdict needs: on A549 the FNet-2D arm's two draws disagreed (nucleus
Dice +0.15..+0.20 vs +0.01..+0.02 over the same baseline).

Registers the unext2_segaux_seed1 eval token and puts the leaf on the
7-day wall with the rest of the UNeXt2-3D fits (same measured recipe).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
Brings in the eval standardization fixes (#499 GT-fit CP feature space,
#500 float32 CP min/max, #501 CP z-clip at +/-20), the MicroMS3IM
calibration fixes (#502, #506), the cubic 0.9.0a2 pin (#503), the
40-48 GB eval GPU constraint (#504) and the Cytoland checkpoint-dir fix.
No conflicts; paths.py auto-merged. dynacell tools + test_paths +
test_benchmark_config_composition pass on the merged tree (2677).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

The changes require final human review because they are too complex or risky for automated approval.

Review effort: Balanced
Findings: None

What changed in this PR

This PR adds Spotlight v2 experiment recipes and isolated evaluation waves to compare segmentation-aware training arms with their corresponding baselines across model families.

Changes:

  • Adds seed replicates, loss-weight sweeps, and generated fit and prediction leaves.
  • Adds Otsu-based C-cond masks and histogram-matched evaluation controls.
  • Registers model tokens and routes Spotlight evaluations outside the canonical paper-output directories.
File Description
applications/​dynacell/​tools/​generate_grouped_eval_configs_test.py Updated as part of this pull request.
applications/​dynacell/​tests/​test_paths.py Updated as part of this pull request.
applications/​dynacell/​tests/​test_benchmark_config_composition.py Updated as part of this pull request.
applications/​dynacell/​src/​dynacell/​mask_conditioning.py Updated as part of this pull request.
applications/​dynacell/​src/​dynacell/​evaluation/​paths.py Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​pix2pix3d_unetvit_v2_seed1/​ipsc_confocal/​predict__ipsc_confocal.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​pix2pix3d_unetvit_v2_seed1/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​pix2pix3d_unetvit_v2_seed1/​ipsc_confocal/​predict__a549_mantis_denv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​pix2pix2d_unetvit_seed1/​ipsc_confocal/​predict__a549_mantis_zikv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​pix2pix2d_unetvit_seed1/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​pix2pix2d_unetvit_seed1/​ipsc_confocal/​predict__a549_mantis_denv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet3d_paper_segaux_seed1/​ipsc_confocal/​predict__ipsc_confocal.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet3d_paper_segaux_seed1/​ipsc_confocal/​predict__a549_mantis_zikv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet3d_paper_segaux_seed1/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet3d_paper_segaux_seed1/​ipsc_confocal/​predict__a549_mantis_denv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet3d_paper_segaux_halfw/​ipsc_confocal/​predict__ipsc_confocal.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet3d_paper_segaux_halfw/​ipsc_confocal/​predict__a549_mantis_zikv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet3d_paper_segaux_halfw/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet3d_paper_segaux_halfw/​ipsc_confocal/​predict__a549_mantis_denv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet3d_paper_segaux_doublew/​ipsc_confocal/​predict__ipsc_confocal.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet3d_paper_segaux_doublew/​ipsc_confocal/​predict__a549_mantis_zikv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet3d_paper_segaux_doublew/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet3d_paper_segaux_doublew/​ipsc_confocal/​predict__a549_mantis_denv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet3d_paper_seed1/​ipsc_confocal/​predict__a549_mantis_zikv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet3d_paper_seed1/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet3d_paper_seed1/​ipsc_confocal/​predict__a549_mantis_denv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet2d_segaux_seed1/​ipsc_confocal/​predict__ipsc_confocal.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet2d_segaux_seed1/​ipsc_confocal/​predict__a549_mantis_zikv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet2d_segaux_seed1/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet2d_segaux_seed1/​ipsc_confocal/​predict__a549_mantis_denv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet2d_seed1/​ipsc_confocal/​predict__a549_mantis_zikv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet2d_seed1/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fnet2d_seed1/​ipsc_confocal/​predict__a549_mantis_denv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fcmae_vscyto3d_scratch_v2_seed1/​ipsc_confocal/​predict__ipsc_confocal.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fcmae_vscyto3d_scratch_v2_seed1/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fcmae_vscyto2d_scratch_seed1/​ipsc_confocal/​predict__a549_mantis_zikv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fcmae_vscyto2d_scratch_seed1/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​fcmae_vscyto2d_scratch_seed1/​ipsc_confocal/​predict__a549_mantis_denv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​celldiff_ccond/​ipsc_confocal/​predict__ipsc_confocal__iterative.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​celldiff_ccond/​ipsc_confocal/​predict__a549_mantis_zikv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​celldiff_ccond/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​celldiff_ccond/​ipsc_confocal/​predict__a549_mantis_denv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​celldiff_2d_seed1/​ipsc_confocal/​predict__a549_mantis_zikv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​celldiff_2d_seed1/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​celldiff_2d_seed1/​ipsc_confocal/​predict__a549_mantis_denv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​celldiff_2d_ccond/​ipsc_confocal/​predict__ipsc_confocal.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​celldiff_2d_ccond/​ipsc_confocal/​predict__a549_mantis_zikv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​celldiff_2d_ccond/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​nucleus/​celldiff_2d_ccond/​ipsc_confocal/​predict__a549_mantis_denv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​pix2pix3d_unetvit_v2_seed1/​ipsc_confocal/​predict__ipsc_confocal.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​pix2pix3d_unetvit_v2_seed1/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​pix2pix2d_unetvit_seed1/​ipsc_confocal/​predict__a549_mantis_zikv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​pix2pix2d_unetvit_seed1/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​pix2pix2d_unetvit_seed1/​ipsc_confocal/​predict__a549_mantis_denv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​fnet2d_segaux_seed1/​ipsc_confocal/​predict__ipsc_confocal.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​fnet2d_segaux_seed1/​ipsc_confocal/​predict__a549_mantis_zikv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​fnet2d_segaux_seed1/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​fnet2d_segaux_seed1/​ipsc_confocal/​predict__a549_mantis_denv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​fnet2d_seed1/​ipsc_confocal/​predict__a549_mantis_zikv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​fnet2d_seed1/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​fnet2d_seed1/​ipsc_confocal/​predict__a549_mantis_denv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​fcmae_vscyto3d_scratch_v2_seed1/​ipsc_confocal/​predict__ipsc_confocal.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​fcmae_vscyto3d_scratch_segaux_seed1/​ipsc_confocal/​predict__ipsc_confocal.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​fcmae_vscyto2d_scratch_seed1/​ipsc_confocal/​predict__a549_mantis_zikv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​fcmae_vscyto2d_scratch_seed1/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​fcmae_vscyto2d_scratch_seed1/​ipsc_confocal/​predict__a549_mantis_denv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​fcmae_vscyto2d_scratch_l1segaux/​ipsc_confocal/​predict__ipsc_confocal.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​fcmae_vscyto2d_scratch_l1segaux/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​fcmae_vscyto2d_scratch_l1seed1/​ipsc_confocal/​predict__ipsc_confocal.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​fcmae_vscyto2d_scratch_l1seed1/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​fcmae_vscyto2d_scratch_l1/​ipsc_confocal/​predict__a549_mantis_zikv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​fcmae_vscyto2d_scratch_l1/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​fcmae_vscyto2d_scratch_l1/​ipsc_confocal/​predict__a549_mantis_denv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​celldiff_2d_seed1/​ipsc_confocal/​predict__a549_mantis_zikv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​celldiff_2d_seed1/​ipsc_confocal/​predict__a549_mantis_mock.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​membrane/​celldiff_2d_seed1/​ipsc_confocal/​predict__a549_mantis_denv.yml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​_internal/​leaf/​grouped/​spotlight_v2_nucleus_ipsc__wave2f/​eval_grouped.yaml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​_internal/​leaf/​grouped/​spotlight_v2_nucleus_ipsc__wave2e/​eval_grouped.yaml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​_internal/​leaf/​grouped/​spotlight_v2_nucleus_ipsc__wave2d/​eval_grouped.yaml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​_internal/​leaf/​grouped/​spotlight_v2_nucleus_ipsc__wave1c/​eval_grouped.yaml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​_internal/​leaf/​grouped/​spotlight_v2_nucleus_a549_zikv__wave2f/​eval_grouped.yaml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​_internal/​leaf/​grouped/​spotlight_v2_nucleus_a549_zikv__wave2b/​eval_grouped.yaml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​_internal/​leaf/​grouped/​spotlight_v2_nucleus_a549_zikv__wave1c/​eval_grouped.yaml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​_internal/​leaf/​grouped/​spotlight_v2_nucleus_a549_mock__wave2f/​eval_grouped.yaml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​_internal/​leaf/​grouped/​spotlight_v2_nucleus_a549_mock__wave2b/​eval_grouped.yaml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​_internal/​leaf/​grouped/​spotlight_v2_nucleus_a549_mock__wave1c/​eval_grouped.yaml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​_internal/​leaf/​grouped/​spotlight_v2_nucleus_a549_denv__wave2f/​eval_grouped.yaml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​_internal/​leaf/​grouped/​spotlight_v2_nucleus_a549_denv__wave2b/​eval_grouped.yaml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​_internal/​leaf/​grouped/​spotlight_v2_nucleus_a549_denv__wave1c/​eval_grouped.yaml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​_internal/​leaf/​grouped/​spotlight_v2_membrane_ipsc__wave2f/​eval_grouped.yaml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​_internal/​leaf/​grouped/​spotlight_v2_membrane_ipsc__wave2c/​eval_grouped.yaml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​_internal/​leaf/​grouped/​spotlight_v2_membrane_ipsc__wave1c/​eval_grouped.yaml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​_internal/​leaf/​grouped/​spotlight_v2_membrane_a549_zikv__wave2e/​eval_grouped.yaml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​_internal/​leaf/​grouped/​spotlight_v2_membrane_a549_zikv__wave1c/​eval_grouped.yaml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​_internal/​leaf/​grouped/​spotlight_v2_membrane_a549_mock__wave1c/​eval_grouped.yaml Updated as part of this pull request.
applications/​dynacell/​configs/​benchmarks/​virtual_staining/​_internal/​leaf/​grouped/​spotlight_v2_membrane_a549_denv__wave1c/​eval_grouped.yaml Updated as part of this pull request.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

alxndrkalinin and others added 4 commits September 29, 2026 14:40
…copying them

Generated leaves are byte-identical (282 leaves, 0 written). Three things
change inside the generator:
- The C-cond threshold placeholder and the comment `_render` spliced in
  were dead once "otsu" replaced the val-tuned value (0 of 282 leaves
  matched). CCOND_THRESHOLDS held "otsu" for both baselines, so it is
  now the single constant CCOND_THRESHOLD.
- l1segaux and l1seed1 re-wrote the segaux and seed deltas inline. They
  now compose l1 with segaux (at the l1-calibrated weight) and go through
  the second-draw path. SEED_SOURCES replaces the `_seed1` suffix rule so
  l1seed1, which has no underscore, can use it.
- A second draw inherits its source arm's 7-day wall through `_long_wall`
  instead of being listed in LONG_WALL_MODELS by hand.

Found by /simplify on PR #507.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
…erator tests

Seven tests each called build_leaves() (~6-8 s per call, 282 leaves).
They only read the result, so a module-scoped fixture generates it once:
the file went from 150 s to 121 s wall (one run each). The weight-sweep
test compares against _FIT_RENAMES instead of an inline copy, and the
count test's docstring no longer claims the seed replicates are
iPSC-only (seed1 and l1 predict the A549 legs too).

Found by /simplify on PR #507.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
…rator's ARMS

_SPOTLIGHT_ARM_MODELS listed every v2 arm by hand, and a test asserted it
equalled the v1 arms, the histmatch controls and {arm.model for arm in
ARMS}. The skip list is now built from exactly that expression, so a new
arm is skipped without a sixth registration edit, and the test that only
restated the definition is gone. test_walk_predictions_skips_spotlight_arms
still checks the skip behaviour. generate_spotlight_v2_leaves imports only
the standard library and yaml, so the sibling import adds no cycle.

Found by /simplify on PR #507.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
The wave2b and wave2c comments sat above wave2f, leaving both blocks
uncommented, and the wave1 note still described seed replicates and
recipe probes that moved to later waves. Comments only: the parsed
roster is identical.

Found by /simplify on PR #507.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
alxndrkalinin and others added 2 commits September 29, 2026 14:46
…g it out

HCSPredictionWriter zero-fills its store (create_zeros), so an unwritten
mask-source window reads back as constant 0.0, not NaN, and the NaN check
never fired. The Otsu path then returned an all-background mask for it,
and a float threshold did the same, so C-cond would condition on "no
nuclei" without an error. A real prediction window is never exactly
constant, so CondMaskSource.read now raises on any constant window,
whatever the threshold. The test covers an unwritten window under both
thresholds, next to a written one that still reads.

Found by internal review of PR #507.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
…tor docstring

The module docstring still said the ccond predict leaves carry a string
PLACEHOLDER threshold that fails at parse; they read `threshold: otsu`.

Found by internal review of PR #507.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

The changes require final human review because they are too complex or risky for automated approval.

Review effort: Balanced
Findings: None

…aw that exists

The allow-list crossed both organelles with segaux_seed1, which also
named nucleus/fcmae_vscyto3d_scratch_segaux_seed1, a leaf the generator
never emits. The list's rule is that only measured slow fits get the long
wall, so a phantom entry would quietly grant it to any leaf later created
under that name. segaux_seed1 is now listed for membrane only.

Found by internal review of PR #507.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

One or more issues must be addressed before approval.

Review effort: Balanced
Findings: 1 High severity

Open (1)

…ding C-cond windows

A partly written FNet mask window mixes predicted values with the
writer's zero fill. It is not constant, so the constant-window guard
missed it, and Otsu then treated the unwritten zeros as background. No
pixel test can tell such a window from a finished one. CondMaskSource.read
now refuses any position whose channel lacks the writer's completion
marker (viscy_prediction_complete with a source_shape). That covers
unwritten, partly written and pre-marker stores. The constant-window
check stays only where it means something: Otsu has no split on a
constant window.

All 272 positions of the eight live C-cond mask sources (fnet2d_segaux,
fnet3d_paper_segaux x 4 legs) carry a complete marker whose source TYX
matches the array, so no current C-cond input is refused.

Addresses the Copilot review of PR #507.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

The changes require final human review because they are too complex or risky for automated approval.

Review effort: Balanced
Findings: None

Resolved since last review (1)

Scores the CELL-Diff A549 nucleus legs that finished after wave2f: the
CELL-Diff-2D C-cond arm re-predicted with the Otsu threshold (all three
legs), the CELL-Diff-3D segaux MOCK/ZIKV legs and the first CELL-Diff-2D
seed1 A549 leg. wave1 now lists exactly the 17 CELL-Diff A549 legs still
predicting, including the CELL-Diff-2D seed1 and membrane segauxself legs
it had not tracked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gwn9hwgT8uJSoWaCxCAm8J
@alxndrkalinin
alxndrkalinin merged commit d7f0015 into dynacell-models Sep 30, 2026
26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants